use std::time::Duration;

use crate::api::prelude::*;
use anyhow::anyhow;
use axum::response::{sse::Event, IntoResponse, Sse};
use carpet::base::error::ServerError;
use template_api::api::demo::sse::*;
use futures::stream::StreamExt;
use tokio::spawn;

#[derive(Debug, Handler)]
pub struct HandlerImpl;


#[impl_handler(HandleDef_)]
impl HandlerImpl {
    
    async fn _handle(self, data: Json<RequestData>) -> Result<SseResponse<ResponseData>, ServerError> {
        let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel::<ResponseData>();
        let stream = async_stream::stream! {
            while let Some(msg) = rx.recv().await {
                yield msg;
            }
        };
        let stream = stream.map(|msg| {
            let data = serde_json::to_string(&msg).map_err(|e| anyhow!("Failed to serialize message: {}", e));
            data.map(|data| Event::default().data(data))
        });
        let response = Sse::new(stream).keep_alive(
            axum::response::sse::KeepAlive::new()
                .interval(Duration::from_secs(30))
                .text("keep-alive-text"),
        ).into_response();
        spawn(async move {
            let mut count = 0;
            let data = data.0;
            loop {
                if count > 10 {
                    break;
                }
                let send_result = tx.send(ResponseData { content: data.title.clone() });
                if let Err(e) = send_result {
                    error!("Error sending message: {}", e);
                    break;
                }
                count += 1;
                tokio::time::sleep(Duration::from_secs(1)).await;
            }
        });
        Ok(SseResponse::new(Box::new(response)))
    }
    
}
